#include "fwMessageService.h"
#include "fwLog.h"

MessageService * MessageService::m_pInstance = NULL;

MessageService::MessageService()
:m_iCount(0)
{
	LOGIDBG("Init MSGService\n");
	m_lstSubscribers.resize(0);
}

MessageService::~MessageService()
{
	LOGIDBG("Destroy MSGService\n");
}


MessageService * MessageService::GetInstance()
{
	if (!m_pInstance)
		m_pInstance = new MessageService();
	return m_pInstance;
}

void MessageService::DestroyInstance()
{
	SAFE_DEL(m_pInstance);
}

void MessageService::Alloc()
{
	m_lstSubscribers.resize(0);
}

void MessageService::Clear()
{
	m_lstSubscribers.clear();
	m_iCount = 0;
}

void MessageService::Process(Publisher publisher)
{
	for (int i = 0; i < m_iCount; i++)
	{
		Subscriber subscriber = m_lstSubscribers.at(i);
		if (strcmp(subscriber.Tag, publisher.Tag) == 0)
		{
			subscriber.RecallFunc(publisher.Sender, publisher.Extra);
		}
	}
}

void MessageService::RegisterMessage(const FWobject reciever, char * tag, void(*recallFunc)(const FWobject sender, FWobject extra))
{
	Subscriber subscriber = Subscriber();
	subscriber.Tag = tag;
	subscriber.Reciever = reciever;
	subscriber.RecallFunc = recallFunc;
	m_lstSubscribers.push_back(subscriber);
	m_iCount++;
}

void MessageService::SendMessageTag(const FWobject sender, char * tag, FWobject extra)
{
	Publisher publisher = Publisher();
	publisher.Tag = tag;
	publisher.Sender = sender;
	publisher.Extra = extra;

	Process(publisher);
}


//=================TAGCONTROLL=================//
TagControll* TagControll::Instance = NULL;

TagControll::TagControll(){}
TagControll::~TagControll(){}
void TagControll::Alloc(){
	if (!Instance)
		Instance = new TagControll;
}
void TagControll::Malloc(){
	SAFE_DEL(Instance);
}
void TagControll::Clear(){
	std::map<FWuint, std::vector<_Subscriber>>::iterator temp = m_lstSubscribers.begin();
	for (; temp != m_lstSubscribers.end(); temp++){
		temp->second.clear();
	}
	m_lstSubscribers.clear();
}
void TagControll::ExecuteTag(_Publisher publisher){
	std::map<FWuint, std::vector<_Subscriber>>::iterator temp = m_lstSubscribers.find(publisher.Tag);
	if (temp == m_lstSubscribers.end())
		return;
	FWuint count = temp->second.size();
	for (FWuint i = 0; i < count; i++){
		temp->second.at(i).CallBack(publisher.Sender, publisher.Extra);
	}
}

void TagControll::RegisterTag(FWobject reciever, FWuint tag, void(*callBack)(const FWobject, FWobject)){
	_Subscriber subscrib;
	subscrib.CallBack = callBack;
	subscrib.Reciever = reciever;
	std::map<FWuint, std::vector<_Subscriber>>::iterator temp = m_lstSubscribers.find(tag);
	if (temp == m_lstSubscribers.end()){
		std::vector<_Subscriber> data;
		data.resize(0);
		data.push_back(subscrib);
		m_lstSubscribers[tag] = data;
	}
	else{
		temp->second.push_back(subscrib);
	}
}

void TagControll::SendTag(const FWobject sender, FWuint tag, FWobject extra){
	_Publisher publisher = _Publisher();
	publisher.Tag = tag;
	publisher.Sender = sender;
	publisher.Extra = extra;

	ExecuteTag(publisher);
}